#include "ParamProcessing.h"

// IP地址，端口
std::string IP = "192.168.10.219";
int Upper_Computer_Port = 10000;
int Controller_Port = 7000;
int Communication_Port = 8000;

// 套接字TCP通信
int Upper_Computer_fd;
int Controller_fd;
int Communication_fd;

// 机器人实时坐标
double _robot_x, _robot_y;
std::mutex _Robot_Mutex;
void updateRobot_xy(double x, double y)
{
  std::lock_guard<std::mutex> lock(_Robot_Mutex);
  _robot_x = x;
  _robot_y = y;
}

double getRobot_x()
{
  std::lock_guard<std::mutex> lock(_Robot_Mutex);
  return _robot_x;
}

double getRobot_y()
{
  std::lock_guard<std::mutex> lock(_Robot_Mutex);
  return _robot_y;
}

// TCP字节通信长度
int Upper_Computer_Byte_Length = 2;
int Controller_Byte_Length = 2;

// 全局变量，用于存储接收到的数据
std::vector<uint8_t> ReceivedDataBufferUpper;
std::vector<uint8_t> ReceivedDataBufferController;

// 是否有与相机的子进程运行中
bool IsServerStart = false;
bool IsGetCirclePoint = false;

// 创建相机对象
HikCamera camera;

//  日志相关文件路径
const std::string LogFloderPath = executablePath + "/log/";
const std::string LogFilePath = executablePath + "/log/log.txt";

// 配置参数文件夹，文件
const std::string ParamFloderPath = executablePath + "/Param/";
const std::string ParamFilePath = executablePath + "/Param/Parameters.json";
// 控制器基本配置文件
const std::string ConfigureFilePath = executablePath + "/Param/Configure.json";

// 作业文件
const std::string JobFileFloderPath = executablePath + "/JobFile/";

//  模板匹配相关文件路径
const std::string SaveJsonPath = executablePath + "/template/template.json";
const std::string SaveImageFloderPath = executablePath + "/template/";

//  与上位机Socket通信，发送图像大小
const cv::Size IMAGE_SIZE(256, 256);
const cv::Size AFFINE_SIZE(3, 2);

//  相机与机器人坐标
std::vector<cv::Point2f> CameraCalibrations;
std::vector<cv::Point2f> RobotCalibrations;
int camera_target_x = 600, camera_target_y = 400;
double robot_target_x, robot_target_y;

std::mutex CameraCalibrationsMutex;
void updateCameraCalibrations(std::vector<cv::Point2f> value)
{
  std::lock_guard<std::mutex> lock(CameraCalibrationsMutex);
  CameraCalibrations.resize(value.size());
  copy(value.begin(), value.end(), CameraCalibrations.begin());
}

std::vector<cv::Point2f> getCameraCalibrations()
{
  std::lock_guard<std::mutex> lock(CameraCalibrationsMutex);
  return CameraCalibrations;
}

std::mutex RobotCalibrationsMutex;
void updateRobotCalibrations(std::vector<cv::Point2f> &value)
{
  std::lock_guard<std::mutex> lock(RobotCalibrationsMutex);
  RobotCalibrations.clear();

  for (std::vector<cv::Point2f>::const_iterator it = value.begin(); it != value.end(); ++it)
  {
    RobotCalibrations.push_back(cv::Point2f(Affine[0][0] * it->x + Affine[0][1] * it->y + Affine[0][2], Affine[1][0] * it->x + Affine[1][1] * it->y + Affine[1][2]));
  }
}

std::vector<cv::Point2f> getRobotCalibrations()
{
  std::lock_guard<std::mutex> lock(RobotCalibrationsMutex);
  return RobotCalibrations;
}

// 获取更新机器人抓取状态
std::mutex RobotGraspingMutex;
bool RobotGrasping = false;

void updateRobotGrasping(bool value)
{
  std::lock_guard<std::mutex> lock(RobotGraspingMutex);
  RobotGrasping = value;
}

bool getRobotGrasping()
{
  std::lock_guard<std::mutex> lock(RobotGraspingMutex);
  return RobotGrasping;
}

//  标定点位数据

void JsonCalibrationPoints(std::vector<cv::Point2f> coords)
{

  std::map<std::string, double> Calibration_Points;
  for (int i = 0; i < coords.size(); ++i)
  {
    Calibration_Points["PointNumber"] = i + 1;
    Calibration_Points["PixX"] = coords[i].x;
    Calibration_Points["PixY"] = coords[i].y;
  }
}

//  获取图像宽高参数
std::map<std::string, int> CamWHParam = {{"WidthValue", 2048},
                                         {"HeightValue", 2048}};

std::mutex camWhParamMutex;

void updateCamWHParam(const std::string &key, int value)
{
  std::lock_guard<std::mutex> lock(camWhParamMutex);
  CamWHParam[key] = value;
}

int getCamWHParam(const std::string &key)
{
  std::lock_guard<std::mutex> lock(camWhParamMutex);
  return CamWHParam[key];
}

//  获取图像偏移量参数
std::map<std::string, int> CamXYParam = {{"OffsetX", 0}, {"OffsetY", 0}};

std::mutex CamXYParamMutex;

void updateCamXYParam(const std::string &key, int value)
{
  std::lock_guard<std::mutex> lock(CamXYParamMutex);
  CamXYParam[key] = value;
}

int getCamXYParam(const std::string &key)
{
  std::lock_guard<std::mutex> lock(CamXYParamMutex);
  return CamXYParam[key];
}

//  获取图像二值化参数
std::map<std::string, int> BinarParam = {{"ThresholdValue1", 150},
                                         {"ThresholdValue2", 255}};

std::mutex BinarParamMutex;

void updateBinarParam(const std::string &key, int value)
{
  std::lock_guard<std::mutex> lock(BinarParamMutex);
  BinarParam[key] = value;
}

int getBinarParam(const std::string &key)
{
  std::lock_guard<std::mutex> lock(BinarParamMutex);
  return BinarParam[key];
}

// 获取ROI 圆
std::map<std::string, std::map<std::string, int>> Circle_ROI;
std::mutex CircleROIMutex;

void updateCircleROI(const std::string &key, std::map<std::string, int> value)
{
  std::lock_guard<std::mutex> lock(CircleROIMutex);
  Circle_ROI[key] = value;
}

std::map<std::string, int> getCircleROI(const std::string &key)
{
  std::lock_guard<std::mutex> lock(CircleROIMutex);
  return Circle_ROI[key];
}

//  获取图像圆查找参数
std::map<std::string, int> CircleParam = {{"MinDist", 50},
                                          {"CannyParam", 50},
                                          {"HoughParam", 50},
                                          {"MinRadius", 50},
                                          {"MaxRadius", 500}};

std::mutex CircleParamMutex;

void updateCircleParam(const std::string &key, int value)
{
  std::lock_guard<std::mutex> lock(CircleParamMutex);
  CircleParam[key] = value;
}

int getCircleParam(const std::string &key)
{
  std::lock_guard<std::mutex> lock(CircleParamMutex);
  return CircleParam[key];
}

// ROI区域 矩形检测
std::map<std::string, std::map<std::string, int>> Rentangle_ROI;
std::mutex RentangleROIMutex;

void updateRentangleROI(const std::string &key, std::map<std::string, int> value)
{
  std::lock_guard<std::mutex> lock(RentangleROIMutex);
  Rentangle_ROI[key] = value;
}

std::map<std::string, int> getRentangleROI(const std::string &key)
{
  std::lock_guard<std::mutex> lock(RentangleROIMutex);
  return Rentangle_ROI[key];
}

//  获取图像矩形查找参数
std::map<std::string, int> RentangleParam = {{"ThresholdValue1", 100},
                                             {"ThresholdValue2", 200},
                                             {"MinArea", 100},
                                             {"MaxArea", 0}};

std::mutex RentangleParamMutex;

void updateRentangleParam(const std::string &key, int value)
{
  std::lock_guard<std::mutex> lock(RentangleParamMutex);
  RentangleParam[key] = value;
}

int getRentangleParam(const std::string &key)
{
  std::lock_guard<std::mutex> lock(RentangleParamMutex);
  return RentangleParam[key];
}

// ROI区域 模板匹配
std::map<std::string, std::map<std::string, int>> Template_ROI;
std::mutex TemplateROIMutex;

void updateTemplateROI(const std::string &key, std::map<std::string, int> value)
{
  std::lock_guard<std::mutex> lock(TemplateROIMutex);
  Template_ROI[key] = value;
}

std::map<std::string, int> getTemplateROI(const std::string &key)
{
  std::lock_guard<std::mutex> lock(TemplateROIMutex);
  return Template_ROI[key];
}

//  获取图像模板匹配模板参数
std::map<std::string, struct TemplateParam> TemplateParamMap;

cv::Mat templateImg;
cv::Mat cropped_img;
TemplateParam templateP;

cv::Mat inputTempl;
std::mutex inputTemplMutex;
void updateinputTempl(cv::Mat img)
{
  std::lock_guard<std::mutex> lock(inputTemplMutex);
  inputTempl = img;
}

cv::Mat getinputTempl()
{
  std::lock_guard<std::mutex> lock(inputTemplMutex);
  return inputTempl;
}

std::mutex templatePMutex;
void updatetemplateP(TemplateParam templateP_tmp)
{
  std::lock_guard<std::mutex> lock(templatePMutex);
  templateP = templateP_tmp;
}

TemplateParam gettemplateP()
{
  std::lock_guard<std::mutex> lock(templatePMutex);
  return templateP;
}

std::mutex TemplateParamMutex;
void updateTemplateParam(const std::string &key, struct TemplateParam value)
{
  std::lock_guard<std::mutex> lock(TemplateParamMutex);

  std::map<std::string, struct TemplateParam>::iterator pos =
      TemplateParamMap.find(key);
  if (pos != TemplateParamMap.end())
  {
    TemplateParamMap[key] = value;
  }
  else
  {
    TemplateParamMap.insert(
        std::pair<std::string, struct TemplateParam>(key, value));
  }
}

struct TemplateParam getTemplateParam(const std::string &key)
{
  std::lock_guard<std::mutex> lock(TemplateParamMutex);
  return TemplateParamMap[key];
}

void TemplateParamMapWrite(
    std::map<std::string, struct TemplateParam> &TemplateParamMap)
{
  Json::Value templateParamMapJson;

  for (const auto &entry : TemplateParamMap)
  {
    const std::string &templateId = entry.first;
    const TemplateParam &templateParam = entry.second;

    Json::Value templateParamJson;
    templateParamJson["TemplateId"] = templateParam.TemplateId;
    templateParamJson["TemplateName"] = templateParam.TemplateName;

    Json::Value templatePointsJson;
    for (const auto &point : templateParam.TemplatePoints)
    {
      Json::Value pointJson;
      for (const auto &coord : point.second)
      {
        pointJson[coord.first] = coord.second;
      }
      templatePointsJson[point.first] = pointJson;
    }

    templateParamJson["TemplatePoints"] = templatePointsJson;

    templateParamMapJson[templateId] = templateParamJson;
  }

  // 将 Json 数据写入文件
  std::cout << "SaveJsonPath:    " << SaveJsonPath << std::endl;
  std::ofstream outFile(SaveJsonPath, std::ios::trunc);
  outFile << templateParamMapJson;
  outFile.close();
}

void TemplateParamMapRead(
    std::map<std::string, struct TemplateParam> &TemplateParamMap)
{

  // 从文件读取 JSON 数据
  std::ifstream inFile(SaveJsonPath);
  if (!inFile.good())
  {
    std::cerr << "Error: Template file not found at path: " << SaveJsonPath
              << std::endl;
    return;
  }
  Json::Value templateParamMapJson;
  inFile >> templateParamMapJson;
  inFile.close();

  // 从 Json 数据中恢复 TemplateParamMap

  for (const auto &templateId : templateParamMapJson.getMemberNames())
  {
    const Json::Value &templateParamJson = templateParamMapJson[templateId];

    TemplateParam templateParam;
    templateParam.TemplateId = templateParamJson["TemplateId"].asString();
    templateParam.TemplateName = templateParamJson["TemplateName"].asString();

    const Json::Value &templatePointsJson = templateParamJson["TemplatePoints"];
    for (const auto &pointName : templatePointsJson.getMemberNames())
    {
      const Json::Value &pointJson = templatePointsJson[pointName];

      for (const auto &coordName : pointJson.getMemberNames())
      {
        int coordValue = pointJson[coordName].asInt();
        templateParam.TemplatePoints[pointName][coordName] = coordValue;
      }
    }

    updateTemplateParam(templateId, templateParam);
  }
}
